package com.ruoyi.common.yh.api.aop;


import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.ApiConfig;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.constant.RedisConstant;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.filter.RepeatedlyRequestWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.core.NamedThreadLocal;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * chenmm
 */
@ControllerAdvice
public class AuthenticationInterceptor implements HandlerInterceptor {
    private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("StopWatch-StartTime");
    protected final Logger logger = LoggerFactory.getLogger(AuthenticationInterceptor.class);
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ApiConfig apiConfig;


    public static boolean judgeYesterday(Date paramDate) throws ParseException {

        Date date = new Date();

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        String todayStr = format.format(date);

        //得到今天零时零分零秒这一时刻

        Date today = format.parse(todayStr);

        //与今日零时零分零秒比较

        if((today.getTime()-paramDate.getTime())>0 && (today.getTime()-paramDate.getTime())<86400000) {

            return true;

        }

        return false;

    }
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      //  errrBody=null;
        startTimeThreadLocal.set(System.currentTimeMillis());
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 判断接口是否需要登录
       LoginRequired methodAnnotation = method.getAnnotation(LoginRequired.class);
        // 有 @LoginRequired 注解，需要认证
        if (methodAnnotation != null) {
            // 执行认证
            String token = request.getHeader("token");  // 从 http 请求头中取出 token

            if (token == null) {

                throw new CustomException("token过期，请重新登录", HttpStatus.UNAUTHORIZED);
            }
            SysUser businesTUser =   redisCache.getCacheObject(RedisConstant.API_LOGIN_USER_TOKEN+"_"+token);
            if(null==businesTUser){
                throw new CustomException("token过期，请重新登录",  HttpStatus.UNAUTHORIZED);
            }
            if(StringUtils.isBlank(businesTUser.getUserName())){
                throw new CustomException("未获取手机号",  HttpStatus.UNAUTHORIZED);
            }

            businesTUser.setLoginDate(new Date());
            redisCache.setCacheObject(RedisConstant.API_LOGIN_USER_TOKEN+"_"+token,businesTUser,apiConfig.getTokenExpireTime(), TimeUnit.DAYS);
            //redisCache.getCacheMap(RedisConstant.API_LOGIN_USER_ONLINE);
            Map countMap = new ConcurrentHashMap<String,Object>();
            long currentTime = System.currentTimeMillis();
            countMap.put(businesTUser.getUserName(),businesTUser.getUserType()+"_"+currentTime);
            redisCache.setCacheMap(RedisConstant.API_LOGIN_USER_ONLINE,countMap);
            Calendar calendar = Calendar.getInstance();
            int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24小时制
            redisCache.setCacheMap(RedisConstant.API_LOGIN_USER_HOUR_ONLINE+"_"+hour,countMap); //按小时存储用户
            redisCache.expire(RedisConstant.API_LOGIN_USER_HOUR_ONLINE+"_"+hour,180,TimeUnit.MINUTES);//设置过期时间

            return true;
        }

            return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        /*log.debug("当前返回的状态：" + httpServletResponse.getStatus());*/

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        /*log.debug("当前返回的状态：" + httpServletResponse.getStatus());
*/


    }

}
